/* GJB-文件的访问-GN-WJXT_006
 * 使用系统提供的文件系统的编程接口，编写程序检测文件的各种访问方式。方式包括读、写、重读、重写、追加写、定位、文件属性设置。
 *
 * GJB-文件的并发访问-GN-WJXT_007
 * 文件的并发访问:使用系统提供的文件系统的编程接口，编写程序检测多进程并发访问同一文件或目录。访问方式包括读、写、定位和属性设置
 *
 * 参数：
 * 	1：进程数，默认为1进程
*/
#include <stdio.h>
#include <sys/stat.h>
#include <sys/types.h>

//读写文件
#define	FILEPATH "/var/tmp/testfile.txt"
//线程并发数
#define FORK_NUM 1

#define FILE_TXT "write :helloworld"
#define APPEND_TXT "append :helloworld\n"

int fork_opt(long long forks);

int file_opt(char *filepath, char *filetxt){
	FILE *rw_fd=NULL;
	char read_str[1024]={};
	struct stat buf;
	
//	printf("File path :%s\n",filepath);
	rw_fd = fopen(filepath,"a+");
	if (rw_fd == NULL){
		printf("Can't find %s\n",filepath);
		return -1;
	}

	// 写	
	fputs(FILE_TXT,rw_fd);
	fputs("\n",rw_fd);
	
	// 追加写
	fwrite(APPEND_TXT,sizeof(APPEND_TXT),1,rw_fd);

	// 定位
	fseek(rw_fd,sizeof(APPEND_TXT),SEEK_SET);

	// 读
	fread(read_str,sizeof(APPEND_TXT),1,rw_fd);

	printf("read_str = %s",read_str);
	fclose(rw_fd);

	// 文件属性	
	stat(filepath,&buf);
	printf("old file size:%d. mode :%o\n", buf.st_size,buf.st_mode);

	chmod(filepath,S_IRUSR|S_IWUSR|S_IXUSR);
	stat(filepath,&buf);
	printf("new file size:%d. mode :%o\n", buf.st_size,buf.st_mode);

	printf("\n");
}

int main(int argc,char* argv[])
{
	long long fork_num = 0;
	if (argc == 2){
		sscanf(argv[1], "%d", &fork_num);
	}else{
		fork_num = FORK_NUM;
	}

	fork_opt(fork_num);	
	while(1){
		sleep(1);
	}
	return 0;
}

int fork_opt(long long forks){
	long long i = 0;
	int pid = 0;

	for (i = 0; i < forks; ++i){
		switch ( pid = fork() ){
		case 0:
			while ( 1 ){
				printf("PID = %d\n",getpid());
				file_opt(FILEPATH, FILE_TXT);
				sleep(1);
			}
		case -1:
			printf("fork failed\n");
		default:
			printf("Dad \n");
		}
	}	
}
